#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <unistd.h>
#include <getopt.h>
#include <signal.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <event.h>
#include <cfulist.h>
#include "l.h"

struct event iteratorev;
struct timeval iteratorevinterval = { .tv_sec = 3, .tv_usec = 0 };
struct event_base *base = NULL;

int cnt = 0;
int lasttime = 0;
int ret = 0;
char buf[1024] = {0};
char *dptr = buf;

void iterator_cb(evutil_socket_t fd, short event, void *user_data)
{
    l_d("runing count:--------->%d", cnt);
    cfulist_t *ls = (cfulist_t *)user_data;
    char *data = NULL;
    size_t data_size = 0;

    int32_t now = (int32_t)time(NULL);
    if(now - lasttime < 20) { l_d("times not up"); goto timesnotup; }
    if(ret == 0){
        dptr = buf;
        dptr += sprintf(dptr, "{");
        ret = cfulist_each_data(ls, (void **)&data, &data_size);
        if(ret == 0) { l_d("each:this is null, ret:0"); lasttime = now; }
        else{ l_d("cnt:%d data:%s, ret:%d", cnt, data, ret); dptr += sprintf(dptr, "%s,", data); }
    }
    else{
        ret = cfulist_next_data(ls, (void **)&data, &data_size);
        if(ret == 0) { l_d("this is null, ret:0"); lasttime = now; }
        else{ l_d("cnt:%d data:%s, ret:%d", cnt, data, ret); dptr += sprintf(dptr, "%s,", data); }
    }

    if(now == lasttime){ l_d("--->publish '%s%d}'", buf, now); }
timesnotup:
    printf("\n");
    cnt += 1;
    event_add(&iteratorev, &iteratorevinterval); //redo
}

int main (int argc, char **argv)
{
    cfulist_t *linklist = cfulist_new();

    //把代码段(字符串常量)添加进去，则不能修改也不能free
    //把栈内一片空间添加进去，则可以修改但请保证生命周期
    //把堆内一片空间添加进去，则可以修改最后用完手动free
    cfulist_push_data(linklist, "hello", 5);
    cfulist_push_data(linklist, "world", 5);
    printf("%lu entries\n\n", cfulist_num_entries(linklist));


    //event
    base = event_base_new();
    if (base == NULL) { l_e("event_base_new() failed"); return -1; }
    event_assign(&iteratorev, base, -1, EV_TIMEOUT, iterator_cb, linklist);
    event_add(&iteratorev, &iteratorevinterval);
    event_base_dispatch(base);

    l_d(PROG "exiting");
    event_base_free(base);
    cfulist_destroy(linklist);

    return (0);
}
